package com.sojson.project.tool.gen.service.impl;

import java.io.IOException;
import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sojson.project.tool.gen.constant.GenConstants;
import com.sojson.project.tool.gen.dao.GenTableColumnDao;
import com.sojson.project.tool.gen.dao.GenTableDao;
import com.sojson.project.tool.gen.entity.dto.GenTableDto;
import com.sojson.project.tool.gen.entity.dto.GenTablePageDto;
import com.sojson.project.tool.gen.entity.po.GenTable;
import com.sojson.project.tool.gen.entity.po.GenTableColumn;
import com.sojson.project.tool.gen.entity.vo.GenTableColumnVo;
import com.sojson.project.tool.gen.entity.vo.GenTableVo;
import com.sojson.project.tool.gen.service.GenTableService;
import com.sojson.project.tool.gen.util.GenUtil;
import com.sojson.util.BeanUtil;
import com.sojson.util.StringUtil;
import com.sojson.util.token.TokenUtil;

/**
 * 代码生成业务表Service实现类
 * 
 * @author liu
 * @date 2022-10-28
 */
@Service
public class GenTableServiceImpl extends ServiceImpl<GenTableDao, GenTable> implements GenTableService {

    @Resource
    private GenTableDao genTableDao;
    @Resource
    private GenTableColumnDao genTableColumnDao;

    /**
     * 通过iD更新
     * 
     * @param dto
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(GenTableDto dto) {
        String options = JSON.toJSONString(dto.getParams());
        dto.setOptions(options);

        GenTable genTable = new GenTable();
        BeanUtil.copyBeanProp(genTable, dto);
        int row = genTableDao.updateById(genTable);

        if (row > 0) {
            for (GenTableColumn cenTableColumn : dto.getColumns()) {
                genTableColumnDao.updateById(cenTableColumn);
            }
        }
        return true;
    }

    /**
     * 通过对象查找
     * 
     * @param dto
     * @return
     */
    @Override
    public List<GenTableVo> list(GenTableDto dto) {
        List<GenTableVo> list = genTableDao.list(dto);
        return list;
    }

    /**
     * 通过对象分页查找
     * 
     * @param dto
     * @return
     */
    @Override
    public List<GenTableVo> page(GenTablePageDto dto) {
        List<GenTableVo> page = genTableDao.page(dto);
        return page;
    }

    /**
     * 通过id列表删除
     * 
     * @param ids
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeByIds(Collection<? extends Serializable> ids) {
        genTableDao.deleteBatchIds(ids);
        genTableColumnDao.deleteByTableIds(ids);
        return true;
    }

    /**
     * 通过对象删除
     * 
     * @param dto
     * @return
     */
    @Override
    public boolean removeByDto(GenTableDto dto) {
        genTableDao.removeByDto(dto);
        return true;
    }

    /**
     * 清空数据
     * 
     * @return
     */
    @Override
    public boolean clear() {
        genTableDao.clear();
        return true;
    }

    /**
     * 通过iD查找
     * 
     * @param id
     * @return
     */
    @Override
    public GenTableVo findById(String id) {
        GenTableVo findById = genTableDao.findById(id);
        setTableFromOptions(findById);
        return findById;
    }

    /**
     * 设置代码生成其他选项值
     * 
     * @param genTable
     */
    public void setTableFromOptions(GenTableVo genTable) {
        JSONObject paramsObj = JSONObject.parseObject(genTable.getOptions());
        if (StringUtil.isNotBlankObject(paramsObj)) {
            String treeCode = paramsObj.getString(GenConstants.TREE_CODE);
            String treeParentCode = paramsObj.getString(GenConstants.TREE_PARENT_CODE);
            String treeName = paramsObj.getString(GenConstants.TREE_NAME);
            String parentMenuId = paramsObj.getString(GenConstants.PARENT_MENU_ID);
            String parentMenuName = paramsObj.getString(GenConstants.PARENT_MENU_NAME);

            genTable.setTreeCode(treeCode);
            genTable.setTreeParentCode(treeParentCode);
            genTable.setTreeName(treeName);
            genTable.setParentMenuId(parentMenuId);
            genTable.setParentMenuName(parentMenuName);
        }
    }

    /**
     * 从数据库获取表信息
     * 
     * @param dto
     * @return
     */
    @Override
    public List<GenTableVo> dbList(GenTableDto dto) {
        List<GenTableVo> dbList = genTableDao.dbList(dto);
        return dbList;
    }

    /**
     * 从数据库获取表信息
     * 
     * @param dto
     * @return
     */
    @Override
    public List<GenTableVo> dbPage(GenTablePageDto dto) {
        List<GenTableVo> dbPage = genTableDao.dbPage(dto);
        return dbPage;
    }

    /**
     * 导入表结构
     * 
     * @param dto
     * @return
     * @throws IOException 
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean importGenTable(List<GenTableVo> dto) throws IOException {
        String operName = TokenUtil.getUserId();
        for (GenTableVo table : dto) {
            String tableName = table.getTableName();
            // 初始化表信息
            GenUtil.initTable(table, operName);

            GenTable genTable = new GenTable();
            BeanUtil.copyBeanProp(genTable, table);
            int row = genTableDao.insert(genTable);
            table.setId(genTable.getId());
            if (row > 0) {
                // 保存列信息
                List<GenTableColumnVo> columns = genTableColumnDao.dbListByTableName(tableName);
                for (GenTableColumnVo column : columns) {
                    // 初始化字段信息
                    GenUtil.initColumnField(column, table);

                    GenTableColumn genTableColumn = new GenTableColumn();
                    BeanUtil.copyBeanProp(genTableColumn, column);
                    genTableColumnDao.insert(genTableColumn);
                }
            }
        }
        return false;
    }

    /**
     * 同步数据库
     * 
     * @param tableName
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean synchDb(String tableName) {
        // 获取表信息
        GenTableVo table = genTableDao.findByTableName(tableName);

        // 获取表已经存在的字段
        List<GenTableColumnVo> tableColumns = table.getColumns();
        List<String> tableColumnNames =
            tableColumns.stream().map(GenTableColumnVo::getColumnName).collect(Collectors.toList());

        // 获取表所有的字段
        List<GenTableColumnVo> dbTableColumns = genTableColumnDao.dbListByTableName(tableName);
        List<String> dbTableColumnNames =
            dbTableColumns.stream().map(GenTableColumnVo::getColumnName).collect(Collectors.toList());

        // 将不存在的字段添加进去
        dbTableColumns.forEach(column -> {
            if (!tableColumnNames.contains(column.getColumnName())) {
                GenUtil.initColumnField(column, table);

                GenTableColumn genTableColumn = new GenTableColumn();
                BeanUtil.copyBeanProp(genTableColumn, column);
                genTableColumnDao.insert(genTableColumn);
            }
        });

        // 将不是此表的字段删除
        List<GenTableColumnVo> delColumns = tableColumns.stream()
            .filter(column -> !dbTableColumnNames.contains(column.getColumnName())).collect(Collectors.toList());
        if (delColumns != null && delColumns.size() > 0) {
            List<String> columnsIds = delColumns.stream().map(GenTableColumnVo::getId).collect(Collectors.toList());
            genTableColumnDao.deleteBatchIds(columnsIds);
        }
        return true;
    }

    /**
     * 生成代码(自定义路径)
     * 
     * @param dto
     * @return
     */
    @Override
    public void genCode(List<String> ids) {
        // TODO Auto-generated method stub

    }

}